/**
 * 一条issue
 */

import React from 'react';
import PropTypes from 'prop-types';
import { Tag, Balloon } from '@teamix/ui';
import { YunxiaoIcon } from '@alife/devops-ui';
import hljs from 'utils/hl.js';
import MarkdownIt from 'markdown-it';
import milt from 'markdown-it-link-target';
import ListLoading from 'atComponents/ListLoading';
import intl from '../../locale';

const { Tooltip } = Balloon;
const md = new MarkdownIt({
  html: true,
}).use(milt, {
  target: '_blank',
});

export default class Issue extends React.Component {
  static propTypes = {
    // 在库安全默认展开
    isInProjectSecurity: PropTypes.bool,
  };

  static defaultProps = {
    isInProjectSecurity: false,
  };

  constructor(props) {
    super(props);

    this.state = {
      isDetailVisible: false,
      rule: '',
    };
  }

  componentDidMount() {
    // 在库安全默认展开
    if (this.props.isInProjectSecurity) {
      this.setState({ isDetailVisible: true });
      this.props.forceUpdateDialog();
    }
  }

  color = { Major: 'blue', Critical: 'orange', Blocker: 'red', default: undefined };

  onIssueDetailToggle = () => {
    const { isDetailVisible } = this.state;
    this.setState({ isDetailVisible: !isDetailVisible });
    this.props.forceUpdateDialog();
  };

  onIssueDetailShow = () => {
    this.setState({ isDetailVisible: true });
    this.props.forceUpdateDialog();
  };

  // hover到issue卡片时，高亮issue命中的行
  onMouseEnter = () => {
    const { issue } = this.props;
    const { id } = issue;

    document.querySelectorAll(`.blob-line-issue-${id}`).forEach((item) => {
      const originalClass = item.getAttribute('class');
      item.setAttribute('class', `${originalClass} blob-line-acitve`);
    });

    this.onIssueDetailShow();
  };

  // 鼠标离开issue卡片时，取消高亮issue命中的行
  onMouseLeave = () => {
    document.querySelectorAll('.blob-line-acitve').forEach((item) => {
      const className = item.getAttribute('class');
      item.setAttribute('class', className.replace(' blob-line-acitve', ''));
    });
  };

  render() {
    const { issue, filters } = this.props;
    const { isDetailVisible, rule } = this.state;

    // $CQ_CODE_FILE_PATH_PREFIX$ 是要替换为文件链接的标识
    const issueDesc = issue.description
      ? issue.description.replace(/\$CQ_CODE_FILE_PATH_PREFIX\$/g, '')
      : '';

    return (
      <div
        className={`issue ${issue.level.toLocaleLowerCase()} status-${issue.status} ${
          issue.no_desc ? 'no-desc' : ''
        }`}
        onMouseEnter={this.onMouseEnter}
        onMouseLeave={this.onMouseLeave}
      >
        <div className="issue-header" onClick={this.onIssueDetailToggle}>
          <div className="issue-header-level">
            <Tag color={this.color[issue.level] || this.color.default}>{issue.level}</Tag>
          </div>
          <div
            className="issue-header-title"
            dangerouslySetInnerHTML={{ __html: md.render(issue.title || '') }}
          />
          {issue.status === 'Closed' ? (
            <Tag className="issue-header-status" shape="normal">
              {intl.get({
                id: 'code-assets.components.buildResultIssues.issue.Resolved',
                defaultMessage: '已解决',
              })}
            </Tag>
          ) : null}
          <div className="issue-header-right">
            <div className="issue-header-right-item">
              <Tooltip
                trigger={
                  <span>
                    {intl.get({
                      id: 'code-assets.components.buildResultIssues.issue.TheFirst',
                      defaultMessage: '第',
                    })}
                    {issue.begin_line}
                    {intl.get({
                      id: 'code-assets.components.buildResultIssues.issue.Line',
                      defaultMessage: '行',
                    })}
                    {issue.end_line && issue.end_line !== issue.begin_line ? (
                      <span>
                        {intl.get(
                          {
                            id: 'code-assets.components.buildResultIssues.issue.LineIssueendline',
                            defaultMessage: '-第{issueEndLine}行',
                          },
                          { issueEndLine: issue.end_line },
                        )}
                      </span>
                    ) : null}
                  </span>
                }
              >
                {issue.end_line !== issue.begin_line
                  ? intl.get(
                      {
                        id: 'code-assets.components.buildResultIssues.issue.FoundInLinesIssuebeginlineTo',
                        defaultMessage: '发现于文件的第 {issueBeginLine} 行至第 {issueEndLine} 行',
                      },
                      { issueBeginLine: issue.begin_line, issueEndLine: issue.end_line },
                    )
                  : intl.get(
                      {
                        id: 'code-assets.components.buildResultIssues.issue.FoundInLineIssuebeginlineOf',
                        defaultMessage: '发现于文件的第 {issueBeginLine} 行',
                      },
                      { issueBeginLine: issue.begin_line },
                    )}
              </Tooltip>
            </div>
            <div className="issue-header-right-item">
              <YunxiaoIcon size="xs" type={`arrow-${isDetailVisible ? 'up' : 'right'}-2-line`} />
            </div>
          </div>
        </div>
        {isDetailVisible ? (
          <div className="issue-body">
            {rule === 'waiting4fetch' ? (
              <ListLoading />
            ) : (
              <div>
                {rule ? (
                  <div className="issue-rule">
                    <div className="issue-rule-title">
                      <div className="issue-rule-name">{rule.name}</div>
                      <div className="issue-rule-info">
                        <div className="issue-rule-info-item">
                          {intl.get({
                            id: 'code-assets.components.buildResultIssues.issue.Category',
                            defaultMessage: '类别：',
                          })}
                          {filters.category.find((item) => item.value === rule.category).key}
                        </div>
                        <div className="issue-rule-info-item">
                          {intl.get(
                            {
                              id: 'code-assets.components.buildResultIssues.issue.ScanPlugInRuledimension',
                              defaultMessage: '扫描插件：{ruleDimension}',
                            },
                            { ruleDimension: rule.dimension },
                          )}
                        </div>
                      </div>
                    </div>
                    <div className="issue-rule-section">
                      <div className="issue-rule-section-title">
                        {intl.get({
                          id: 'code-assets.components.buildResultIssues.issue.ProblemDescription',
                          defaultMessage: '问题描述',
                        })}
                      </div>
                      {rule.description}
                    </div>
                    {rule.suggestion ? (
                      <div className="issue-rule-section">
                        <div className="issue-rule-section-title">
                          {intl.get({
                            id: 'code-assets.components.buildResultIssues.issue.ModificationSuggestions',
                            defaultMessage: '修改建议',
                          })}
                        </div>
                        <pre className="issue-rule-suggestion">
                          <code>
                            <div
                              dangerouslySetInnerHTML={{
                                __html: hljs.highlight(
                                  rule.language || 'java',
                                  rule.suggestion || '',
                                  true,
                                ).value,
                              }}
                            />
                          </code>
                        </pre>
                      </div>
                    ) : null}
                  </div>
                ) : (
                  <div>
                    {issueDesc ? (
                      <div className="issue-rule">
                        <div className="issue-rule-section-title">
                          {intl.get({
                            id: 'code-assets.components.buildResultIssues.issue.ProblemDescription',
                            defaultMessage: '问题描述',
                          })}
                        </div>
                        <div dangerouslySetInnerHTML={{ __html: md.render(issueDesc || '') }} />
                      </div>
                    ) : (
                      <div className="issue-rule-not-find">
                        {intl.get({
                          id: 'code-assets.components.buildResultIssues.issue.NoRelevantRulesAndTroubleshooting',
                          defaultMessage: '未查询到相关规则及修复建议',
                        })}
                      </div>
                    )}
                  </div>
                )}
              </div>
            )}
          </div>
        ) : null}
      </div>
    );
  }
}
